<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="umsroot.css">
<TITLE>
Stores
</TITLE>
</HEAD>
<BODY >
<A HREF="umsroot052.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot049.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot054.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc130">9.4</A>&nbsp;&nbsp;Stores</H2>

<A NAME="@default451"></A>
<A NAME="@default452"></A>
A <B>store</B> is an anonymous object which can be used to store information
across failures. A typical application is aggregating information across
multiple solutions. Note that, if it is not necessary to save information
across backtracking, the use of the
<A HREF="../bips/lib/hash/index.html"><B>library(hash)</B></A><A NAME="@default453"></A>
is more appropriate and efficient than the facilities described here.<BR>
<BR>
A store is a hash table which can store arbitrary terms under arbitrary
ground keys. Modifications of a store, as well as the entries within it,
survive backtracking. The basic operations on stores are entering and
looking up information under a key, or retrieving the store contents as
a whole.<BR>
<BR>
Stores come in two flavours: anonymous stores are created with
<A HREF="../bips/kernel/storage/store_create-1.html"><B>store_create/1</B></A><A NAME="@default454"></A>
and referred to by handle, while named stores are created with a
<A HREF="../bips/kernel/storage/store-1.html"><B>store/ 1</B></A><A NAME="@default455"></A>
declaration and referred to by their name within a module. 
If possible, anonymous stores should be preferred because they make it
easier to write robust, reentrant code. For example, an anonymous store
automatically disappears when the system backtracks over its creation,
or when the store handle gets garbage collected. Named stores, on the
other hand, must be explicitly destroyed in order to free the
associated memory. <BR>
<BR>
Data is entered into a store using
<A HREF="../bips/kernel/storage/store_set-3.html"><B>store_set/3</B></A><A NAME="@default456"></A>
and retrieved using
<A HREF="../bips/kernel/storage/store_get-3.html"><B>store_get/3</B></A><A NAME="@default457"></A>.
It is possible to retrieve all keys with
<A HREF="../bips/kernel/storage/stored_keys-2.html"><B>stored_keys/2</B></A><A NAME="@default458"></A>
or the full contents of the table with
<A HREF="../bips/kernel/storage/stored_keys_and_values-2.html"><B>stored_keys_and_values/2</B></A><A NAME="@default459"></A>.
Entries can be deleted via
<A HREF="../bips/kernel/storage/store_delete-2.html"><B>store_delete/2</B></A><A NAME="@default460"></A> or
<A HREF="../bips/kernel/storage/store_erase-1.html"><B>store_erase/1</B></A><A NAME="@default461"></A>.<BR>
<BR>
<A NAME="@default462"></A>
<A NAME="@default463"></A>
<A NAME="@default464"></A>
A typical use of stores is for the implementation of memoization.
The following is an implementation of the Fibonacci function, which
uses a store to remember previously computed results.
It consists of the declaration of a named store, a wrapper predicate
fib/2 that handles storage and lookup of results, and the standard
recursive definition fib_naive/2:
<PRE CLASS="verbatim">
    :- local store(fib).

    fib(N, F) :-
        ( store_get(fib, N, FN) -&gt;
            F = FN                    % use a stored result
        ;
            fib_naive(N, F),
            store_set(fib, N, F)      % store computed result
        ).

    fib_naive(0, 0).
    fib_naive(1, 1).
    fib_naive(N, F) :-
        N1 is N-1, N2 is N-2,
        fib(N1, F1), fib(N2, F2),
        F is F1 + F2.
</PRE>Using this definition, large function values can be efficiently computed:
<PRE CLASS="verbatim">
    ?- fib(300, F).
    F = 222232244629420445529739893461909967206666939096499764990979600
    Yes (0.00s cpu)
</PRE>
The next example shows the use of an anonymous store, for computing
how many solutions of each kind a goal has.
The store is used to maintain counter values, using the
solution term as the key to distinguish the different counters:
<PRE CLASS="verbatim">
    solutions_profile(Sol, Goal, Profile) :-
        store_create(Store),
        (
            call(Goal),
            store_inc(Store, Sol),
            fail
        ;
            stored_keys_and_values(Store, Profile)
        ).
</PRE>Running this code produces for example:
<PRE CLASS="verbatim">
    ?- solutions_profile(X, member(X, [a, b, c, b, a, b]), R).
    X = X
    R = [a - 2, b - 3, c - 1]
    Yes (0.00s cpu)
</PRE>
<HR>
<A HREF="umsroot052.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot049.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot054.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
